﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Kugar.Core.BaseStruct;
using Kugar.Core.ExtMethod;
using SqlSugar;

namespace Kugar.Tools.SQLHelper.SQLGenerator
{
    public partial class SqlTable<TDbContext, TTable> where TTable : class,new()
	{
		public SqlTable (TTable dbContext)
		{
			DbContext=dbContext;
		}

		#region Query 相关函数

		public virtual TTable[] QuerySql(string whereStr,object paramters=null)
		{
			return Client.Queryable<TTable>().Where(whereStr,paramters).ToList().ToArrayEx();
		}

		public virtual async Task<TTable[]> QuerySqlAsync(string whereStr,object paramters=null)
		{
			return Client.Queryable<TTable>().Where(whereStr,paramters).ToList().ToArrayEx();
		}


        public virtual TTable[] QuerySql(string fields, string whereStr)
		{
			return Client.Queryable<TTable>().Where(whereStr).Select(fields).ToList().ToArrayEx();
		}

		public virtual async Task<TTable[]> QuerySqlAsync(string fields, string whereStr)
		{
			return (await Client.Queryable<TTable>().Where(whereStr).Select(fields).ToListAsync()).ToArrayEx();
		}
        
		public virtual ISugarQueryable<TTable> Query()
		{
			return Client.Queryable<TTable>();
		}

		public virtual VM_PagedList<TTable> QueryWithPaged(Expression<Func<TTable, bool>> whereExp ,int pageIndex,int pageSize)
		{
			 int count=0;

			 var lst=Query().Where(whereExp).ToPageList(pageIndex,pageSize,ref count);

			 var result=new VM_PagedList<TTable>(lst,pageIndex,pageSize,count);

			 return result;
		}

		public virtual async Task<VM_PagedList<TTable>> QueryWithPagedAsync(Expression<Func<TTable, bool>> whereExp ,int pageIndex,int pageSize)
		{
			 //int count=0;

			 var lst=await Query().Where(whereExp).ToPageListAsync(pageIndex,pageSize,0);

			 var result=new VM_PagedList<TTable>(lst.Key, pageIndex, pageSize, lst.Value);

			 return result;
		}

		public virtual VM_PagedList<TResult> QueryWithPaged<TResult>(Expression<Func<TTable, bool>> whereExp ,int pageIndex, int pageSize)
		{
			 int count=0;

			 var lst=Query().Where(whereExp).Select<TResult>().ToPageList(pageIndex,pageSize,ref count);

			 var result=new VM_PagedList<TResult>(lst,pageIndex,pageSize,count);

			 return result;
		}

		public virtual async Task<VM_PagedList<TResult>> QueryWithPagedAsync<TResult>(Expression<Func<TTable, bool>> whereExp ,int pageIndex, int pageSize)
		{
			 int count=0;

			 var lst=await Query().Where(whereExp).Select<TResult>().ToPageListAsync(pageIndex,pageSize,0);

			 var result=new VM_PagedList<TResult>(lst.Key, pageIndex, pageSize, lst.Value);

			 return result;
		}

		public virtual bool Exists(Expression<Func<TTable, bool>> whereExp)
		{
			return Query().Where(whereExp).Any();
		}

		public virtual async Task<bool> ExistsAsync(Expression<Func<TTable, bool>> whereExp)
		{
			return await Query().Where(whereExp).AnyAsync();
		}

		public virtual TTable FirstOrDefault(Expression<Func<TTable, bool>> whereExp)
		{
			try
			{
				return Query().Where(whereExp).First();
			}
			catch{
				return null;
			}
		}

		public virtual async Task<TTable> FirstOrDefaultAsync(Expression<Func<TTable, bool>> whereExp)
		{
			try
			{
				return await Query().Where(whereExp).FirstAsync();
			}
			catch{
				return null;
			}
		}


		#endregion

		#region Delete 相关函数

        public virtual int Delete(string whereStr)
		{
			return Client.Deleteable<TTable>().Where(whereStr).ExecuteCommand();
		}

		public virtual async Task<int> DeleteAsync(string whereStr)
		{
			return await Client.Deleteable<TTable>().Where(whereStr).ExecuteCommandAsync();
		}

        public virtual int Delete(Expression<Func<TTable, bool>> whereExp)
		{
			return Client.Deleteable<TTable>(whereExp).ExecuteCommand();
		}

		public virtual async Task<int> DeleteAsync(Expression<Func<TTable, bool>> whereExp)
		{
			return await Client.Deleteable<TTable>(whereExp).ExecuteCommandAsync();
		}

        
		#endregion

		#region Insert 相关函数

		public virtual int Insert(TTable entity)
		{
		
			return Client.Insertable<TTable>(entity).ExecuteReturnIdentity();
		}

		public virtual async Task<int> InsertAsync(TTable entity)
		{
			return await Client.Insertable<TTable>(entity).ExecuteReturnIdentityAsync();
		}

		public virtual int Insert(params TTable[] entities)
		{
			return Client.Insertable<TTable>(entities).ExecuteCommand();
		}

		public virtual async Task<int> InsertAsync(params TTable[] entities)
		{
			return await Client.Insertable<TTable>(entities).ExecuteCommandAsync();
		}



		#endregion

		/// <summary>
        /// 更新表,返回一个UpdaterBudler
        /// </summary>
        /// <param name="whereExp"></param>
        /// <returns></returns>
        public IUpdateable<TTable> Update(Expression<Func<TTable, bool>> whereExp)
        {
            return Client.Updateable<TTable>().Where(whereExp);
        }

        public virtual  string TableName => "TTable";

        protected virtual SqlSugarClient Client => DbContext.DbClient;

        public virtual TDbContext DbContext { get;  }
        
	}
}
